EC2のユーザデータでnvmとNode.jsをインストールしようとしたら苦労したこと
こんにちは、ゲームソリューション部のsoraです。
今回は、EC2のユーザデータでnvmとNode.jsをインストールしようとしたら苦労したことについて書いていきます。
今回使用するAMIはAmazon Linux2023です。
上手くいったユーザデータ
まず先に上手くいったユーザデータは以下です。
#!/bin/bash
# Update the package list and install necessary packages
dnf update -y
# nvmとnodejsのインストール(マルチパート形式)
Content-Type: multipart/mixed; boundary="//"
MIME-Version: 1.0
--//
Content-Type: text/cloud-config; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment; filename="cloud-config.txt"
#cloud-config
cloud-init directives
--//
Content-Type: text/x-shellscript; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment; filename="userdata.txt"
#!/bin/bash
# nvmのインストール
if ! su - ec2-user -c "command -v nvm" > /dev/null 2>&1; then
su - ec2-user -c "curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.0/install.sh | bash"
su - ec2-user -c "source ~/.bashrc"
fi
# nodejsのインストール
if ! su - ec2-user -c "command -v node" > /dev/null 2>&1; then
su - ec2-user -c "nvm install --lts"
fi
--//--
結論に至るまでに試したこと
ユーザデータを使わずにインストール
ユーザデータでのインストールをする前に、手動でインストールして上手くいくかを確認してみます。
sudo dnf update -y
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.0/install.sh | bash
source ~/.bashrc
nvm install --lts
実行後にインストールされているかの確認をしてみると、問題なくバージョンが確認できます。
nvm --version
0.40.0
node --version
v20.17.0
上手くいったコマンドをそのままユーザデータに記載
上手くいったコマンドをそのままユーザデータに記載して起動してみます。
ユーザデータのため、sudoは消しています。
dnf update -y
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.0/install.sh | bash
source ~/.bashrc
nvm install --lts
これは上手くいきませんでした。
理由としては、ユーザデータはrootで実行されるため、.nvmディレクトリがroot配下に作成され、ec2-userから呼び出せないためです。
パスを変更したりしたものの、結局上手くいかなかったです。(パスの設定が悪いかもですが)
ユーザデータでec2-userとして実行するように書き換える
先ほどはrootでnvmのインストールをして、.nvmディレクトリがroot配下に作成されたため、ec2-userとしてコマンドを実行するように書き換えてみます。
(su -
を書いていますがおそらく不要です)
dnf update -y
su - ec2-user -c "curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.0/install.sh | bash"
su - ec2-user -c "source ~/.bashrc"
su - ec2-user -c "nvm install --lts"
これだとうまくいかなかったため、ユーザデータ実行時のログを見てみます。
cat /var/log/cloud-init-output.log
# (以下抜粋)
init__.py[WARNING]: Unhandled non-multipart (text/x-not-multipart) userdata: 'b'su - ec2-user -c "curl -'...'
マルチパート形式で記述がされておらず、su - ec2-user -c …
が上手く実行できていないみたいです。
マルチパート形式で書き換える
エラーに従ってマルチパート形式で書き換えます。
マルチパート形式で記載すると、インスタンス起動時に毎回実行されてしまうため、if
を入れてnvmとnodejsがインストールされていれば処理をスキップするようにしています。
#!/bin/bash
# Update the package list and install necessary packages
dnf update -y
# nvmとnodejsのインストール(マルチパート形式)
Content-Type: multipart/mixed; boundary="//"
MIME-Version: 1.0
--//
Content-Type: text/cloud-config; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment; filename="cloud-config.txt"
#cloud-config
cloud-init directives
--//
Content-Type: text/x-shellscript; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment; filename="userdata.txt"
#!/bin/bash
# nvmのインストール
if ! su - ec2-user -c "command -v nvm" > /dev/null 2>&1; then
su - ec2-user -c "curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.0/install.sh | bash"
su - ec2-user -c "source ~/.bashrc"
fi
# nodejsのインストール
if ! su - ec2-user -c "command -v node" > /dev/null 2>&1; then
su - ec2-user -c "nvm install --lts"
fi
--//--
起動したインスタンスにて以下コマンドを実行してみると、nvmとnodejsがインストールされていることが確認できました。
nvm --version
0.40.0
node --version
v20.17.0
最後に
今回は、EC2のユーザデータでnvmとNode.jsをインストールしようとしたら苦労したことを記事にしました。
どなたかの参考になると幸いです。